package com.kantboot.functional.im.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.kantboot.functional.im.domain.entity.FunctionalImPushMessage;
import com.kantboot.functional.im.domain.entity.FunctionalImPushMessageBroker;
import com.kantboot.functional.im.domain.entity.FunctionalImPushMessagePayload;
import com.kantboot.functional.im.dto.FunctionalImPushMessageDTO;
import com.kantboot.functional.im.event.ImPushEvent;
import com.kantboot.functional.im.repository.FunctionalImPushMessageBrokerRepository;
import com.kantboot.functional.im.repository.FunctionalImPushMessagePayloadRepository;
import com.kantboot.functional.im.repository.FunctionalImPushMessageRepository;
import com.kantboot.functional.im.service.IFunctionalImPushMessageService;
import com.kantboot.util.common.exception.BaseException;
import jakarta.annotation.Resource;
import jakarta.transaction.Transactional;
import org.springframework.context.ApplicationContext;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;

@Service
public class FunctionalImPushMessageServiceImpl implements IFunctionalImPushMessageService {

    @Resource
    ApplicationContext applicationContext;

    @Resource
    private FunctionalImPushMessageRepository repository;

    @Resource
    private FunctionalImPushMessageBrokerRepository brokerRepository;

    @Resource
    private FunctionalImPushMessagePayloadRepository payloadRepository;

    @Async
    @Transactional
    @Override
    public void push(FunctionalImPushMessageDTO message) {
        FunctionalImPushMessage pushMessage = new FunctionalImPushMessage();
        pushMessage.setTypeCode(message.getTypeCode());
        pushMessage.setPushTypeCode(message.getPushTypeCode());
        pushMessage.setUserId(message.getUserId());
        pushMessage.setTitle(message.getTitle());
        pushMessage.setContent(message.getContent());
        pushMessage.setTtl(message.getTtl());
        // 保存消息
        FunctionalImPushMessage save = repository.save(pushMessage);

        FunctionalImPushMessagePayload payload = null;
        if(null!=save.getPayload()) {
            // 构建消息的payload
            payload =
                    new FunctionalImPushMessagePayload()
                            .setMessageId(save.getId())
                            .setEmit(message.getPayload().getEmit())
                            .setData(message.getPayload().getData());

            // 保存消息的payload
            payload=payloadRepository.save(payload);
        }


        // 构建消息的broker
        List<FunctionalImPushMessageBroker> brokers = new ArrayList<>();
        message.getBrokers().forEach(broker -> {
            brokers.add(new FunctionalImPushMessageBroker()
                    .setMessageId(save.getId())
                    .setCode(broker.getCode())
                    .setCid(broker.getCid())
                    .setStatusCode(FunctionalImPushMessageDTO.Broker.STATUS_CODE_NOT_SEND)
            );
        });

        // 保存消息的broker
        List<FunctionalImPushMessageBroker> functionalImPushMessageBrokers = brokerRepository.saveAll(brokers);

        FunctionalImPushMessage result = BeanUtil.copyProperties(save, FunctionalImPushMessage.class);
        result.setPayload(payload).setBrokers(functionalImPushMessageBrokers);

        // 发布事件
        applicationContext.publishEvent(new ImPushEvent(this,result));

    }

    @Override
    public void changeStatusCode(Long brokerId, String statusCode) {
        FunctionalImPushMessageBroker byId = brokerRepository.findById(brokerId).orElseThrow(
                () -> BaseException.of("brokerIdNotExists","brokerId不存在")
        );
        byId.setStatusCode(statusCode);
        brokerRepository.save(byId);
    }
}
